﻿
Imports std

Public Module componentInitializer
    Private initializers As map(Of String, _do(Of String, configParser, Object, Boolean)) = Nothing

    Sub New()
        initializers = New map(Of String, _do(Of String, configParser, Object, Boolean))()
        registerComponents()
    End Sub

    Private Sub registerComponents()
        register(Of storageJobRandomDistributor) _
                (AddressOf storageJobRandomDistributor.initial)
    End Sub

    Private Function initial(ByVal name As String, ByVal config As configParser, ByVal obj As Object) As Boolean
        If istype(Of detector)(obj) Then
            Return detector.initial(name, config, [as](Of detector)(obj))
        ElseIf istype(Of distributor)(obj) Then
            Return distributor.initial(name, config, [as](Of distributor)(obj))
        ElseIf istype(Of gravitation_planet)(obj) Then
            Return gravitation_planet.initial(name, config, [as](Of gravitation_planet)(obj))
        ElseIf istype(Of gravitation_star)(obj) Then
            Return gravitation_star.initial(name, config, [as](Of gravitation_star)(obj))
        ElseIf istype(Of consumer)(obj) Then
            Return consumer.initial(name, config, [as](Of iconsumer)(obj))
        ElseIf istype(Of producer)(obj) Then
            Return producer.initial(name, config, [as](Of iproducer)(obj))
        Else
            Return False
        End If
    End Function

    Public Function initial(ByVal type As String, ByVal name As String,
                            ByVal config As configParser, ByVal obj As Object) As Boolean
        If isemptystring(type) OrElse isemptystring(name) OrElse config Is Nothing OrElse obj Is Nothing Then
            raiseError(errorHandle.errorType.warning, "no type / name / config / object input")
            Return False
        Else
            Dim it As map(Of String, _do(Of String, configParser, Object, Boolean)).iterator = Nothing
            it = initializers.find(strtolower(type))
            If it = initializers.end() Then
                'fail back to common initializer
                Return initial(name, config, obj)
            Else
                Return (+it).second(name, config, obj)
            End If
        End If
    End Function

    Public Function register(ByVal type As String,
                             ByVal initial As _do(Of String, configParser, Object, Boolean)) As Boolean
        type = strtolower(type)
        If initial Is Nothing OrElse isemptystring(type) Then
            Return False
        ElseIf initializers.find(type) <> initializers.end() Then
            raiseError(errorHandle.errorType.warning, "duplicate type ", type, " found")
            Return False
        Else
            initializers(type) = initial
            Return True
        End If
    End Function

    Public Function register(Of T)(ByVal initial As _do(Of String, configParser, Object, Boolean)) As Boolean
        Return register(GetType(T).Name(), initial)
    End Function
End Module
